package thred_02;

/**
 synchronized 同步方法/synchronized(this)代码块
 1.对其他synchronized同步方法或synchronized代码块调用呈阻塞状态，
 2.同一时间只有一个线程可以执行synchronized同步方法中的代码

 synchronized(非this)
 1.在多个线程持有"对象监视器"魏同一个的前提下，同一时间只有一个线程可以执行synchronized同步代码块中的代码
 2.当持有"对象监视器"为同一个对象的前提下，同一时间只有一个线程可以执行synchronized同步代码块中的代码
 */
class MyObject{
}
class ServiceB{
    MyObject object = new MyObject();
    public void testMethod2(MyObject object){
        synchronized (object){
            try {
                System.out.println("method2 get lock time="+System.currentTimeMillis()+"run" +
                        " thread name is "+Thread.currentThread().getName());
                Thread.sleep(2000L);
                System.out.println("method2 release lock time="+System.currentTimeMillis()+"run" +
                        " thread name is "+Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Service{
    MyObject object = new MyObject();
    public void testMethod1(MyObject object){
        synchronized (object){
            try {
                System.out.println("method1 get lock time="+System.currentTimeMillis()+"run" +
                        " thread name is "+Thread.currentThread().getName());
                Thread.sleep(2000L);
                System.out.println("method1 release lock time="+System.currentTimeMillis()+"run" +
                        " thread name is "+Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    class ThreadA extends Thread{
        @Override
        public void run() {
            testMethod1(object);
        }
    }

    class ThreadB extends Thread{
        @Override
        public void run() {
            testMethod1(object);
        }
    }

    class ThreadC extends Thread{
        @Override
        public void run() {
            new ServiceB().testMethod2(object);
        }
    }
    class ThreadD extends Thread{
        @Override
        public void run() {
            new ServiceB().testMethod2(object);
        }
    }
    public static void main(String[] args) {
        Service service = new Service();
        ThreadA threadA = service.new ThreadA();
        ThreadB threadB = service.new ThreadB();
        ThreadC threadC = service.new ThreadC();
        ThreadD threadD = service.new ThreadD();
        threadA.setName("A");
        threadB.setName("B");
        threadC.setName("C");
        threadD.setName("D");
        threadA.start();
        threadB.start();
        threadC.start();
        threadD.start();

    }
}
public class TestThread {

}
